AULA 07 - Funções | Eventos¶


AGENDA¶

  • Funções
  • Exercícios
  • Eventos
  • Controle de formulários
  • DOM
  • Referências
  • Perguntas

1. Funções¶

  • Abrir JSBin.com para executar os códigos.
  • Para aprofundar no assunto, consulte Javscript.info.
  • As funções são blocos de construção fundamentais em Javascript.
  • As funções são definidas utilizando-se a palavra function, seguida do nome e lista de argumentos caso exista. (Verbo + Substantivo)

  • Sintaxe:

function nomeFunção([argumentos])) {
    ... declarações
};
  • Os parâmetros passados podem ser primitivos ou não primitivos (array, objeto). Se houver alteração das propriedades do objeto dentro da função, estas são vistas fora dela também.

1.1. Criando uma função de forma literal¶

// *******************************************
// Criando de forma literal 
// *******************************************

let corOlhos = "azul";

function resetarCor() {
    corOlhos = "verdes";
}

console.log(corOlhos);
resetarCor();
console.log(corOlhos);
Fonte: Autoria própria

1.2. Armazenando em uma variável¶

// *******************************************
// Armazenando em uma variável 
// *******************************************

let corOlhos = "azul";

const funcao2 = function resetarCor() {
    return corOlhos = "verdes";
};

console.log(corOlhos);
console.log("Função2: ", funcao2()); 


// Outro exemplo

let y = function() {
    ... 
};
Fonte: Autoria própria

1.3. Armazenando em um array¶

// ********************************************
// Armazenando em um array
// ********************************************

let a = [ function funcaonome(a, b) { 
            return 1+b+a; 
          }, funcao1, funcao2];

1.4. Armazenando em um atributo de um objeto¶

// ********************************************
// Armazenando em um atributo de um objeto 
// ********************************************

const obj = {}
obj.mostrar = function() {
    return "Hello"; 
};
console.log(obj.mostrar());
Fonte: Autoria própria

1.5. Passando uma função como parâmetro¶

// ********************************************
// Passando uma função como parâmetro 
// ********************************************

function correr(funcao) {
    funcao()
}
correr(function() { console.log('Correndo...') });
Fonte: Autoria própria

1.6. Uma função pode retornar/conter uma função¶

// ********************************************
// Uma função pode retornar/conter uma função 
// ********************************************

function soma(a, b) {
    return function(c) {
        console.log(a + b + c);
    }
};
soma(2, 3)(4);
Fonte: Autoria própria

1.6.1. Exercício 1¶

  • Crie um programa que receba um número e indique se é número primo. Um número é considerado primo quando é divisível somente por 1 e por ele mesmo. Liste os números primos dentro de um intervalo, solicitando o valor máximo.
maximo = prompt("Indique o numero: ");
exibirPrimo(maximo);

function exibirPrimo(maximo) {
    console.log("** Números primos entre 0 e", maximo, "**");
    for (let numero=2; numero <= maximo; numero++) {
        if (numeroPrimo(numero)) console.log(numero);
    }
}

function numeroPrimo(numero) {
    for (let divisor = 2; divisor < numero; divisor++) {
        if (numero % divisor === 0) {
            return false;
        }
    }
    return true;
}

1.6.2. Exercício 2¶

  • Elabore um programa que solicite o nome completo, o endereço completo e exiba estas informações no console. Utilize objeto e funções.
const nome = prompt("Informe seu nome completo: ")
let endereco = {
    logradouro : prompt("Indique o nome da rua: "),
    numero : prompt("Indique o número: "),
    bairro : prompt("Indique o bairro: "),
    cidade : prompt("Indique cidade: "),
}


function exibir(nome, endereco) {
    console.log(nome);
    for (let chave in endereco)
        console.log(chave, endereco[chave]);
}

exibir(nome, endereco);

1.7. Parâmetros e retornos são opcionais e usando template string ${ }¶

// ********************************************
// Parâmetros e retornos são opcionais
// Usando template string ${ }
// ********************************************

function area(larg, alt) {
    const area = larg * alt;
    if (area > 20) {
        console.log(`Valor ${area}m2 acima do permitido!`);
    } else {
        return area;
    }
}

console.log(area(2,2));
console.log(area(2));
console.log(area());
console.log(area(2, 3, 22, 44, 55));
console.log(area(5, 5));
Fonte: Autoria própria
// ****************************
// Parâmetros variáveis 
// ****************************

function soma() {
    let soma = 0;
    for (i in arguments) {
        soma += arguments[i];
    }
    return soma;
}

console.log(soma(1, 2, 3));  
console.log(soma(1.1, 2.3, 3.6));  
console.log(soma());  
console.log(soma(1));  
console.log(soma(1, 2, "Teste"));
Fonte: Autoria própria

1.8. Funções Arrow (Arrow functions)¶

  • Observação:

    • Utilize let para criar variáveis que são realemnte variáveis.
    • Utilize const para criar constantes que não serão modificadas.
  • São um tipo de sintaxe utilizada para escrever funções de forma mais condensada.

  • Consulte Tipscode.

  • Sintaxe:

// Exemplo função sem arrow function

function myFunction() {
    // ... seu codigo aqui
}

// Exemplo função sem arrow function

function meuNome(nome) {
    console.log(nome);
}
meuNome("Ana Paula");


// Exemplo função com arrow function

const myFunction = () => {
    // ... seu codigo aqui 
}

// Exemplo função com arrow function

const meuNome = (nome) => {
    console.log(nome);
}
  • Observação:
    • Se tiver mais de um argumento, é obrigatório usar parênteses (nome, idade, cidade).
    • Se receber somente um argumento, não é obrigatório utilizar os parênteses.
    • Se não receber parâmetro algum, é obrigatório o uso de parênteses.
const mult = (numero) => {
    return numero * 2;
}
console.log(mult(4));
// Se não tivermos mais instruções, somente um `return`, poderemos esrever assim:
const mult = numero => numero * 2;
console.log(mult(4));


// outros exemplos
let mult = function(a) {
    return 2 * a;
}
console.log(mult(4));


mult = (a) => {
   return 2 * a;
}
console.log(mult(4));


mult = a => 2 * a;

1.9. Funções imediatas¶

  • Para aprofundamento do assunto, consulte Pedro Araújo - Funções imediatas JavaScript (IIFE).

  • De acordo com [Pedro Araujo], " IIFE significa Immediately-invoked function expression ".

  • Por que usar funções imediatas?

    • Segundo [Pedro Araujo], por causa do "Encapsulamento! Tenha em mente que variáveis em Javascript têm como escopo a função da qual elas foram definidas (podem ser acessadas somente dentro da função, jamais fora). Ao criar uma função anônima com execução imediata, podemos criar um escopo temporário para nossas funções e variáveis. Com isso evitamos poluição no nosso escopo global e possíveis conflitos de variáveis ou funções com o mesmo nome".
  • Sintaxe:

(function(){})();

// Exemplo 1
(function(){
    let nome = prompt("Indique seu nome: ");
    let x = 'Seja bem vindo,';
    console.log(x, nome);
})();
Fonte: Autoria própria

1.10. Funções de Fábrica¶

  • Dentro do paradigma de orientação a objetos, temos o padrão de projeto conhecido como, Factory.
  • Já sob o paradigma funcional, pode-se utilizar o padrão de projeto conhecido como Factory Functions.

As factory functions são funções que encapsulam as informações dentro de um método e retornam um objeto literal.¶

  • Vantagens: Otimização, e melhor manutenção do código, alterando somente em um lugar, no caso, no construtor.
  • Importante:
    1. Quando as chaves do objeto forem iguais aos nomes das variáveis recebidas na função, não é necessário efetuar a atribuição, basta indicar os nomes das chaves. Vide exemplo em Factory Function sem hardcode.
    2. Para os casos de funções dentro do objeto, basta indicar o nome das funções, sem adicionar a palavra function. Vide exemplo ligar() em Factory Function sem hardcode.
  • Seguindo exemplos de Canal Dev Aprender.
  • Efetuando o cadastro de diversos objetos do tipo celular por meio do uso de factoty function.

Factory Function com hardcode¶

// Funcão criarCelular, com hardcode.

function criarCelular() {
    const celular = {
        marcaCelular: 'ASUS',
        tamanhoTela: {
            vertical: 155,
            horizontal: 75
        },
        capacidadeBateria: 5000,
        ligar: function() {
            console.log("Efetuando a ligação ...");
        }
    }
    return celular;
}
const cel = criarCelular();
console.log(cel);
cel.ligar();
Fonte: Autoria própria
Fonte: Autoria própria Fonte: Autoria própria

Factory Function sem hardcode¶

// Funcão criarCelular, sem hardcode, usando padrão Factory Function.

function criarCelular(marcaCelular, tamanhoTela, capacidadeBateria) {
    return {
        marcaCelular,
        tamanhoTela,
        capacidadeBateria,
        ligar() {
            console.log("Efetuando a ligação ...");
        }
    }
}

const celular1 = criarCelular('Zenfone', 5.5, 5000)
console.log(celular1);
Fonte: Autoria própria
Fonte: Autoria própria Fonte: Autoria própria

1.11. Funções de Construtores¶

  • Construct Functions são similares a Factory Function, porém são escritas de outra forma de codificação.
  • Observação:
    • Até o momento utilizamos a escrita com o padrão de Camel case (umDoisTres).
    • Para Construct Functions, utiliza-se o Pascal case (UmDoisTres).
  • Utiliza a criação de um objeto por meio de new NomeFuncao( ).
// Construct Functions
function Celular(marcaCelular, tamanhoTela, capacidadeBateria) {
    this.marcaCelular = marcaCelular,
    this.tamanhoTela = tamanhoTela,
    this.capacidadeBateria = capacidadeBateria,
    this.ligar = function() {
        console.log("Efetuando ligação ...")
    }
}

const celular = new Celular('Zenfone', 5.5, 5000)
console.log(celular);
Fonte: Autoria própria Fonte: Autoria própria

2. Exercícios¶

2.1. Exercício 1¶

  • Comparando Strings
// Construtor de Função
function Endereco(endereco) {
    this.logradouro = endereco.logradouro,
    this.numero = endereco.numero,
    this.bairro = endereco.bairro,
    this.cidade = endereco.cidade,
}

// variável endereco1
let endereco1 = new Endereco({
    logradouro : prompt("Indique o nome da rua: "),
    numero : prompt("Indique o número: "),
    bairro : prompt("Indique o bairro: "),
    cidade : prompt("Indique cidade: "),
});

// variável endereco2
let endereco2 = new Endereco({
    logradouro : 'Avenida das margaridas',
    numero : '1987',
    bairro : 'Vila das Flores',
    cidade : 'Bragança Paulista',
});


// funcao para verificar se os endereços são iguais
function saoIguais(endereco1, endereco2) {
    // comparando propriedades
    return endereco1.logradouro === endereco2.logradouro && 
    endereco1.cidade === endereco2.cidade &&
    endereco1.numero === endereco2.numero;
}

console.log(saoIguais(endereco1, endereco2));  
// true: endereços possuem valores iguais. Digitei mesmos valores.
// Saída: true

function enderecoReferencia(endereco1, endereco2) {
    // comparando endereco de memoria - referencia
    return endereco1 === endereco2
}

console.log(enderecoReferencia(endereco1, endereco2)); 
// false: aponta para endereco de memoria diferentes
// Saída: false

// variável endereco3
const endereco3 = endereco1;

function enderecoReferencia1(endereco1, endereco3) {
    // comparando endereco de memoria - referencia
    return endereco1 === endereco3
}
console.log(enderecoReferencia1(endereco1, endereco3)); 
// true: aponta para o mesmo endereco de memoria 
// Saída: true

2.2. Exercício 2¶

  • Seguindo exemplos de Canal Dev Aprender.
  • Criar um programa que simule a postagem em um blog. O objeto a ser criado deve conter:
    • título
    • mensagem
    • autor
    • número de vizualizações
    • comentários (autor, mensagens) >> array
    • estado (aovivo ou não)
// criando o objeto
let x = 0;
let continuar = prompt("Deseja postar? S-Sim, N-Não: ").toUpperCase;


while (continuar != 'N') {
    let postagem = {
        titulo: prompt("Indique o título da postagem: "),
        mensagem: prompt("Informe a mensagem: "),
        autor: prompt("Indique o autor: "),
        visualizacoes: x +=1,
        comentarios: [
            { autor: prompt("Indique autor comentário1: "), mensagem: prompt("Informe a mensagem1: ")},
            { autor: prompt("Indique autor comentário2: "), mensagem: prompt("Informe a mensagem2: ")},
        ],
        estado: true,
    };
    console.log(postagem);
    continuar = prompt("Deseja postar? S-Sim, N-Não: ").toUpperCase;
}

2.3. Exercício 3¶

  • Seguindo exemplos de Canal Dev Aprender.
  • Criar um programa que exiba faixas de preços com definições de valores mínimos e máximos. Além de exibir dicas.
let faixas1 = [
{
    tooltip : 'até R$ 700', 
    minimo : 0,
    maximo : 700,
},
{
    tooltip : 'R$ 700 até R$ 1000', 
    minimo : 700,
    maximo : 1000,
},
{
    tooltip : 'acima de R$ 1000', 
    minimo : 1000,
    maximo : 9999999999,
}
];

console.log(faixas1);


// Resolvendo com
// Usando Factory Function
function criarFaixaPreco(tooltip, minimo, maximo) {
    return {
        tooltip,
        minimo,
        maximo,
    }
}

let faixas2 = [
    criarFaixaPreco('até R$ 700', 0, 700),
    criarFaixaPreco('R$ 700 até R$ 1000', 700, 1000),
    criarFaixaPreco('acima de R$ 1000', 1000, 9999999999),
]
console.log(faixas2);


// Resolvendo com
// Usando Contructor
function FaixaPrecos(tooltip, minimo, maximo) {
    this.tooltip = tooltip,
    this.minimo = minimo,
    this.maximo = maximo
}
let faixas3 = new FaixaPrecos('até R$ 700', 0, 700)
console.log(faixas3);

let faixas4 = new FaixaPrecos('R$ 700 até R$ 1000', 700, 1000)
console.log(faixas4);

let faixas5 = new FaixaPrecos('acima de R$ 1000', 1000, 9999999999)
console.log(faixas5);

2.4. Exercício 3 - outra solução¶

let faixas1 = [
{
    tooltip : 'até R$ ', 
    minimo : 0,
    maximo : prompt("Indique o valor máximo: "),
},
{
    tooltip : 'R$ ', 
    minimo : 500,
    maximo : prompt("Indique o valor máximo para segunda pesquisa: "),
},
{
    tooltip : 'acima de R$ ', 
    minimo : 1000,
    maximo : 9999999999,
}
];

faixas1[0].tooltip += String(faixas1[0].maximo);

faixas1[1].tooltip += String(faixas1[0].maximo) + ' até R$ '+ String(faixas1[1].maximo);
faixas1[1].minimo = faixas1[0].maximo;

faixas1[2].tooltip += String(faixas1[1].maximo);
faixas1[2].minimo = faixas1[1].maximo;

console.log(faixas1);

3. Eventos¶

  • Para conhecer e saber como usar, leia os artigos:
    • Javascript.info - Eventos.
    • Javscript.info - Eventos da Interface do Usuário.

3.1. Eventos com o mouse¶

3.1.1. Click em qualquer lugar¶

<!-- Clique em qualquer lugar -->
<p>Click this document to activate the handler.</p>
<script>
  window.addEventListener("click", () => {
    console.log("Você clicou?");
  });
</script>

3.1.2. Clique n vezes no botão¶

<!-- Clique do botao -->
<button>Clique</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Botão selecionado.");
  });
</script>

3.1.3. Clique único no botão¶

<!-- Clique feito uma única vez -->
<button>Clique único</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Feito.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>

3.1.4. Clique com um dos botões¶

<!-- Clique feito com cada um dos botões do mouse -->
<button>Clique com um dos botões do mouse</button>
<script>
  let button = document.querySelector("button");
  button.addEventListener("mousedown", (event) => {
    if (event.button == 0) {
      console.log("Botão esquerdo");
    } else if (event.button == 1) {
      console.log("Botão meio");
    } else if (event.button == 2) {
      console.log("Botão direito");
    }
  });
</script>

3.1.5. Qual dos botões foi selecionado?¶

<!-- Qual botão foi clicado -->
<button>A</button>
<button>B</button>
<button>C</button>
<script>
  document.body.addEventListener("click", (event) => {
    if (event.target.nodeName == "BUTTON") {
      console.log("Clicou", event.target.textContent);
    }
  });
</script>

3.1.6. preventDefault¶

  • O método event.preventDefault() evita o comportamento padrão de um elemento.
  • Se usado em um form, ele impede o envio (submit).
  • Se usado em um ancora, hiperlink (<a>), ele impede a navegação.
<!--
    Para a maioria dos tipos de eventos, os manipuladores de eventos JavaScript são chamados antes que o comportamento padrão ocorra. Se o manipulador não quiser que esse comportamento normal aconteça, normalmente porque já cuidou de manipular o evento, ele pode chamar o preventDefault método no objeto de evento. 
    -->
<a href="https://developer.mozilla.org/" target="_blank">MDN</a>
<script>
  let link = document.querySelector("a");
  link.addEventListener("click", (event) => {
    console.log(“Não executou.”);
    event.preventDefault();
  });
</script>

3.2. Eventos com teclados¶

<!-- Alterna de cor ao manter um letra pressionada -->
<p>Esta página alterna para cor violeta ao manter pressionado a letra V.</p>
<script>
  window.addEventListener("keydown", (event) => {
    if (event.key == "v") {
      document.body.style.background = "violet";
    }
  });
  window.addEventListener("keyup", (event) => {
    if (event.key == "v") {
      document.body.style.background = "";
    }
  });
</script>

3.2.1. Tecla pressionada¶

<!-- Conforme a tecla pressionada -->
<p>Pressione CTRL + barra de espaço.</p>
<script>
  window.addEventListener("keydown", (event) => {
    if (event.key == " " && event.ctrlKey) {
      console.log("Continue!");
    }
  });
</script>

3.3. Outros eventos com o clique do mouse: Marque os pontos com o clique do mouse¶

<!-- Marque os pontos com o clique do mouse -->
<style>
  body {
    height: 200px;
    background: beige;
  }
  .dot {
    height: 8px;
    width: 8px;
    border-radius: 4px; /* cantos arredondados */
    background: blue;
    position: absolute;
  }
</style>
<script>
  window.addEventListener("click", (event) => {
    let dot = document.createElement("div");
    dot.className = "dot";
    dot.style.left = event.pageX - 4 + "px";
    dot.style.top = event.pageY - 4 + "px";
    document.body.appendChild(dot);
  });
</script>

3.3.1. Outros eventos com o clique do mouse: Arraste o bloco para ver a movimentacao¶

<!-- Arraste o bloco para ver a movimentacao -->
<p>
  Clique e mantenha pressionado e arraste pra ver a modificação de largura
  da barra.
</p>
<div style="background: orange; width: 60px; height: 20px;"></div>
<script>
  let lastX; // Tracks the last observed mouse X position
  let bar = document.querySelector("div");
  bar.addEventListener("mousedown", (event) => {
    if (event.button == 0) {
      lastX = event.clientX;
      window.addEventListener("mousemove", moved);
      event.preventDefault(); // Prevent selection
    }
  });

  function moved(event) {
    if (event.buttons == 0) {
      window.removeEventListener("mousemove", moved);
    } else {
      let dist = event.clientX - lastX;
      let newWidth = Math.max(10, bar.offsetWidth + dist);
      bar.style.width = newWidth + "px";
      lastX = event.clientX;
    }
  }
</script>

3.3.2. Uso de barra de progresso na parte superior a medida que rola o scroll¶

<!-- Uso de barra de progresso na parte superior a medida que rola o scroll -->
<style>
  #progress {
    border-bottom: 6px solid blue;
    width: 0;
    position: fixed;
    top: 0;
    left: 0;
  }
</style>
<div id="progress"></div>
<script>
  // Create some content
  document.body.appendChild(
    document.createTextNode("Diversas linhas ".repeat(1000))
  );

  let bar = document.querySelector("#progress");
  window.addEventListener("scroll", () => {
    let max = document.body.scrollHeight - innerHeight;
    bar.style.width = `${(pageYOffset / max) * 100}%`;
  });
</script>

3.3.3. Outros eventos com o clique do mouse: Indicação do que deve ser digitado¶

<!-- Indicação do que deve ser digitado -->
<p>Nome: <input type="text" data-help="Seu nome" /></p>
<p>Idade: <input type="text" data-help="Sua idade" /></p>
<p id="help"></p>

<script>
  let help = document.querySelector("#help");
  let fields = document.querySelectorAll("input");
  for (let field of Array.from(fields)) {
    field.addEventListener("focus", (event) => {
      let text = event.target.getAttribute("data-help");
      help.textContent = text;
    });
    field.addEventListener("blur", (event) => {
      help.textContent = "";
    });
  }
</script>


<!-- Indicação do conteúdo do nome digitado -->
<p>Nome: <input type="text" data-help="Seu nome" id="input" /></p>     <---- Adicionado id="input"
<p>Idade: <input type="text" data-help="Sua idade" /></p>
<p id="help"></p>
<p><span id="result"></span></p>                                       <---- Adicionado
<script>
<!-- Adicionado -->
  input.oninput = function () {
    result.innerHTML = input.value;
  };
<!-- Fim Adicionado -->
  let help = document.querySelector("#help");
  let fields = document.querySelectorAll("input");
  for (let field of Array.from(fields)) {
    field.addEventListener("focus", (event) => {
      let text = event.target.getAttribute("data-help");
      help.textContent = text;
    });
    field.addEventListener("blur", (event) => {
      help.textContent = "";
    });
  }
</script>

3.3.4. Outros eventos com o clique do mouse: Contagem com setInterval¶

<!-- Contagem com setInterval -->
<script>
  let ticks = 0;
  let clock = setInterval(() => {
    console.log("tick", ticks++);
    if (ticks == 10) {
      clearInterval(clock);
      console.log("stop.");
    }
  }, 200);
</script>

4. Utilizando Controle de Formulários¶

  • Javascript.info - Formulários.

Referências¶

  • Esta aula foi elaborada a partir do conteúdo disponibilizado em cada um dos links indicados no próprio texto.


ADS - HTML5, CSS3, JS.
Modelo e formato elaborado pela profa. Ana Paula Müller Giancoli - BSD 2-Clause License. - Julho.2022.

</div> </div>